package com.sbt.springboot.utils;

import com.hankcs.hanlp.seg.common.Term;
import com.hankcs.hanlp.suggest.Suggester;
import com.hankcs.hanlp.tokenizer.NLPTokenizer;
import io.redisearch.AggregationResult;
import io.redisearch.Query;
import io.redisearch.Schema;
import io.redisearch.SearchResult;
import io.redisearch.aggregation.AggregationBuilder;
import io.redisearch.aggregation.SortedField;
import io.redisearch.aggregation.reducers.Reducers;
import io.redisearch.client.Client;
import io.redisearch.client.IndexDefinition;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.util.Pool;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 工具组件
 *
 * @author juwenzhe@cslc.com.cn
 * @date 2020/12/22 14:52
 */
@Service
public class RedisSearch {

    /**
     * 配置redis搜索
     */
    @Bean
    public Client initRedisSearch() {
        String indexName = "test";
        String host = "192.168.248.131";
        int port = 6379;
        String password = "124816";
        int timeout = 300;
        int poolSize = 0;
        return new Client(indexName, host, port);
    }

    /**
     * 创建索引
     */
    public void createIndex(Client client, String title, String body, String price) {
        Schema sc = new Schema()
                .addTextField(title, 5.0)
                .addTextField(body, 1.0)
                .addNumericField(price);
        IndexDefinition rule = new IndexDefinition()
                .setFilter("@age>16")
                .setPrefixes(new String[]{"student:", "pupil:"});
        client.createIndex(sc, Client.IndexOptions.defaultOptions().setDefinition(rule));
    }

    /**
     * 将文档添加到索引
     * fields.put("title", "hello world");
     * fields.put("state", "NY");
     * fields.put("body", "lorem ipsum");
     * fields.put("price", 1337);
     *
     * @param fields f
     */
    public void addDocument(Client client, String docId, Map<String, Object> fields) {
        client.addDocument(docId, fields);
    }

    /**
     * 创建复杂查询
     *
     * @param queryString q
     * @param price       p
     * @return s
     */
    public SearchResult search(Client client, String queryString, String price) {
        Query query = new Query(queryString)
                .addFilter(new Query.NumericFilter(price, 0, 1000))
                .limit(0, Integer.MAX_VALUE);
        return client.search(query);
    }


    /**
     * 聚合查询
     *
     * @param query    q
     * @param price    p
     * @param state    s
     * @param avgprice a
     * @param k        k
     * @return a
     */
    public AggregationResult aggregate(Client client, String query, String price, String state, String avgprice, String k) {
        AggregationBuilder builder = new AggregationBuilder(query)
                .apply("@".concat(price).concat("/1000"), k)
                .groupBy("@".concat(state), Reducers.avg("@".concat(k)).as(avgprice))
                .filter("@".concat(avgprice).concat(">=2"))
                .sortBy(Integer.MAX_VALUE, SortedField.asc("@".concat(state)));
        return client.aggregate(builder);
    }


    /**
     * 分词查询 先分词 在合并
     */
    public List<SearchResult> searchParticiple(Client client, String queryString, String price) {
        List<SearchResult> result = new ArrayList<>();
        //分词
        List<Term> termList = NLPTokenizer.segment(queryString);
        termList.stream().forEach(e -> {
            Query query = new Query(e.word)
                    .addFilter(new Query.NumericFilter(price, 0, 1000))
                    .limit(0, Integer.MAX_VALUE);
            SearchResult search = client.search(query);
            result.add(search);
        });
        return result;
    }

    /**
     * 出推荐查询
     *
     * @param queryString q
     * @param price       p
     * @return l
     */
    public List<SearchResult> searchSuggest(Client client, String queryString, String price) {
        List<SearchResult> result = new ArrayList<>();
        //推荐
        List<String> suggest = new Suggester().suggest(queryString, Integer.MAX_VALUE);
        suggest.stream().forEach(e -> {
            Query query = new Query(e)
                    .addFilter(new Query.NumericFilter(price, 0, 1000))
                    .limit(0, Integer.MAX_VALUE);
            SearchResult search = client.search(query);
            result.add(search);
        });
        return result;
    }


}


